#include "netEvent.h"
#include "event.h"
#include "eventInterface.h"
#include "ESPacketBase.h"
#include "assert.h"

ConnInfo::ConnInfo(int _f, bool _listen){
	fd = _f;
	ptr = NULL;
	isListener = _listen;
}
ConnInfo::~ConnInfo(){
	fd = -1;
	if( ptr != NULL ){
		ptr = NULL;
	}
}

int ConnInfo::getFd(){
	return fd;
}

void ConnInfo::setFd(int _f){
	fd = _f;
}

void ConnInfo::setRecallHandle(netEvent *_p){
	assert( _p != NULL);
	ptr = _p;
}

void ConnInfo::closeConn(){
	event_del(&ev);
	::close(fd);
}

int ConnInfo::sendPacketData(const char *buf, unsigned int size){
	return ::send(fd, buf, size, 0);
}

static event_base *base = NULL;

#if 0
int eventCenter( const int fd, const short Event, void *arg ){
	assert( arg != NULL );
	if( arg == NULL ){
		close(fd);
		return -1;
	}
	ConnInfo *pConn = (ConnInfo *)arg;
	netEvent *pNetInterface = (netEvent *)pConn->ptr;
	assert( pConn != NULL && pNetInterface != NULL );
	static char data[10240];
	int len = ::recv( fd, data, 10240, 0 );
	if( len == 0 ){
		pNetInterface->handleClose();
	}else{
	/*
		Buffer &buf = pConn->ptr->buf;
		buf.pushData(data, len);
		*/
		if( isListener == true ){
			pNetInterface->handleOpen();
		}else{
			pNetInterface->handleRead();
		}
	}
	return 0;
}
#endif

int netInit(){
	base = event_init();
	if( base == NULL ){
		return -1;
	}
	return 0;
}
//上面可能是有问题的部分***
void netReall( const int fd, const short Event, void *args ){

	ConnInfo *pConn = (ConnInfo *)args;
	netEvent *handle = (netEvent *)pConn->ptr;
	//得到数据
	static char buf[10240];
	unsigned int recvLen = ::recv(fd, buf, 10240, 0);
	if( recvLen < 0 ){
		return ;//到底是关了，还是放着。如果放着可能会有句柄泄露
	}
	if( recvLen == 0 ){
		handle->handleClose( args );
		return ;
	}
	if( pConn->isListener == true ){
		handle->handleOpen();
	}else{
		handle->handleRead( buf, recvLen, args);
	}
	return ;
}
int addEvent(ConnInfo &conn, void *args){

	if( conn.getFd() < 0 ){
		return -1;
	}
	event_set(&conn.ev, conn.getFd(), EV_READ | EV_PERSIST, netReall, (void *)&conn);
	event_add(&conn.ev, 0);
	return 0;
}


int delEvent(ConnInfo &conn, bool closeFd){

	if( conn.getFd() > 0 ){
		event_del(&conn.ev);
		if( closeFd ){
			::close(conn.getFd());
		}
	}
	return 0;
}

void loopEvent(){
	event_base_loop(base, 0);
}


//#######################
TimerInfo::TimerInfo(int _id){
	id = _id;
}

TimerInfo::~TimerInfo(){}

int TimerInfo::getId(){
	return id;
}

void TimerInfo::setId(int _id){
	id = _id;
}

void TimerInfo::setRecallHandle(timeEvent *_p){
	assert( _p != NULL);
	ptr = _p;
}


void timerReall( const int fd, const short Event, void *args ){

	TimerInfo *pTimer = (TimerInfo *)args;
	timeEvent *handle = (timeEvent *)pTimer->ptr;
	handle->handleTimeout( pTimer->getId() );

}

int addTimer(TimerInfo &timer, int _t, void *args){
	//event_timer(&timer.ev, timerReall, (void *)&timer);
	evtimer_set(&timer.ev, timerReall, (void *)&timer);
	struct timeval tv;
	tv.tv_usec = 0;
	tv.tv_sec = _t;
	event_add(&timer.ev, &tv);
	return 0;
}
